package drivers

import (
	"time"

	"gitee.com/yelhjt/gocache/config"
	"gitee.com/yelhjt/gocache/core"
	"github.com/go-redis/redis"
)

// Redis 缓存
type redisCache struct {
	// 缓存
	*core.Cache
	// redis 对象
	Redis *redis.Client
	// 配置
	config *config.RedisConfig
}

//----------------------------------
// 实现 CacheInterface 接口 start
//----------------------------------

// 实例化
func NewRedis(conf *config.RedisConfig) core.CacheInterface {

	redis_cache := &redisCache{
		Cache: &core.Cache{
			// 不过期时间
			NoExpire: core.NoExpire,
			// 前缀
			Prefix: conf.Prefix,
			// 缓存数据
			Items: make(map[string]core.Item),
		},
		// 配置
		config: conf,
		// 连接Redis
		Redis: redis.NewClient(&redis.Options{
			Addr:     conf.Addr + ":" + conf.Port, // url
			Password: conf.Passwrod,
			DB:       conf.DBnum, // 数据库
		}),
	}
	// 关闭 redis
	// defer redis_cache.Redis.Close()
	return redis_cache
}

// 设置值 参数1:key  , 参数2:value , 参数2:有效时间 ; 如果存在则直接覆盖
func (redisCache *redisCache) Set(key string, value interface{}, d time.Duration) bool {
	err := redisCache.Redis.Set(key, value, d).Err()
	if err != nil {
		return false
	}
	return true
}

// 设置值 参数1:key  , 参数2:value , 参数2:有效时间 ;如果存在则抛出异常
func (redisCache *redisCache) Add(key string, value interface{}, d time.Duration) error {
	value, err := redisCache.Get(key, value)
	if err == nil {
		return core.CacheExist
	}
	err = redisCache.Redis.Set(key, value, d).Err()
	if err != nil {
		return err
	}
	return nil
}

// 修改值 参数1:key  , 参数2:value , 参数2:有效时间 ; 如果存在则修改,不存在则抛出异常
func (redisCache *redisCache) Replace(key string, value interface{}, d time.Duration) error {
	value, err := redisCache.Get(key, value)
	if err != nil {
		return core.CacheNoExist
	}
	err = redisCache.Redis.Set(key, value, d).Err()
	if err != nil {
		return err
	}
	return nil
}

// 获取值 参数:key
func (redisCache *redisCache) Get(key string, defaultvalue interface{}) (interface{}, error) {
	value, err := redisCache.Redis.Do("Get", key).Result()
	if err != nil {
		return defaultvalue, err
	}
	return value, nil
}

// 清空所有缓存
func (redisCache *redisCache) Flush() {
	redisCache.Redis.Do("FLUSHALL")
}

// 删除某个缓存
func (redisCache *redisCache) Delete(key string) error {
	return redisCache.Redis.Del(key).Err()
}

// 判断键值是否存在
func (redisCache *redisCache) Has(key string) bool {
	value, err := redisCache.Redis.Exists(key).Result()
	if err != nil || value == 0 {
		return false
	} else {
		return true
	}
}

//----------------------------------
// 实现 CacheInterface 接口 end
//----------------------------------
